package cn.zhejianglao.shirotemplate.service.permission.service;

import cn.zhejianglao.shirotemplate.common.model.PageRequest;
import cn.zhejianglao.shirotemplate.common.model.PagedResult;
import cn.zhejianglao.shirotemplate.common.model.PermissionVO;
import cn.zhejianglao.shirotemplate.exception.BusinessException;
import cn.zhejianglao.shirotemplate.exception.ExceptionCode;
import cn.zhejianglao.shirotemplate.service.permission.dao.IPermissionMapper;
import cn.zhejianglao.shirotemplate.service.permission.model.RolePermissionVO;
import cn.zhejianglao.shirotemplate.service.role.dao.IRoleMapper;
import cn.zhejianglao.shirotemplate.service.user.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 权限服务实现类
 */
@Service
public class PermissionService implements IPermissionService {

    @Autowired
    private IPermissionMapper permissionMapper;

    @Autowired
    private IUserService userService;

    @Autowired
    private IRoleMapper roleMapper;

    @Override
    public PagedResult<PermissionVO> list(int size, int page) {
        PageRequest request = new PageRequest(size, page);
        List<PermissionVO> data = permissionMapper.selectByPage(request);
        return new PagedResult<>(data, request);
    }

    @Override
    public void create(PermissionVO permissionVO) {
        if (permissionMapper.selectCountByName(permissionVO.getPermissionName()) > 0) {
            throw new BusinessException(
                    ExceptionCode.Permission.PERMISSION_ALREADY_EXISTS_CODE,
                    ExceptionCode.Permission.PERMISSION_ALREADY_EXISTS_MSG
            );
        }
        Long userId = userService.getCurrentUser().getId();
        permissionVO.setCreatedBy(userId);
        permissionMapper.insert(permissionVO);
    }

    @Override
    public void delete(Long id) {
        if (id == null) {
            throw new BusinessException(
                    ExceptionCode.Param.ILLEGAL_PARAM_CODE,
                    "id 不能为空"
            );
        }
        permissionMapper.deleteById(id);
    }

    @Override
    public void update(PermissionVO permissionVO) {
        if (permissionMapper.selectCountByName(permissionVO.getPermissionName()) == 0) {
            throw new BusinessException(
                    ExceptionCode.Common.RESOURCE_NOT_EXISTS_CODE,
                    ExceptionCode.Common.RESOURCE_NOT_EXISTS_MSG
            );
        }
        Long userId = userService.getCurrentUser().getId();
        permissionVO.setModifiedBy(userId);
        permissionMapper.insert(permissionVO);
    }

    @Override
    public void authorize(RolePermissionVO relation) {
        validationRelation(relation);
        if (permissionMapper.selectCountByRelation(relation) > 0) {
            throw new BusinessException(
                    ExceptionCode.Common.RESOURCE_ALREADY_EXISTS_CODE,
                    ExceptionCode.Common.RESOURCE_ALREADY_EXISTS_MSG
            );
        }
        Long currentUserId = userService.getCurrentUser().getId();
        relation.setCreatedBy(currentUserId);
        permissionMapper.insertRolePermissionRelation(relation);
    }

    @Override
    public void cancelAuthorization(RolePermissionVO relation) {
        validationRelation(relation);
        if (permissionMapper.selectCountByRelation(relation) == 0) {
            throw new BusinessException(
                    ExceptionCode.Common.RESOURCE_NOT_EXISTS_CODE,
                    ExceptionCode.Common.RESOURCE_NOT_EXISTS_MSG
            );
        }
        permissionMapper.deleteRolePermissionRelation(relation);
    }

    /**
     * 校验关系，用户id，角色id在库中都需要存在
     *
     * @param relation 关系
     */
    private void validationRelation(RolePermissionVO relation) {
        if (roleMapper.selectCountById(relation.getRoleId()) == 0) {
            throw new BusinessException(
                    ExceptionCode.Common.RESOURCE_NOT_EXISTS_CODE,
                    "角色不存在"
            );
        }
        if (permissionMapper.selectCountById(relation.getRoleId()) == 0) {
            throw new BusinessException(
                    ExceptionCode.Common.RESOURCE_NOT_EXISTS_CODE,
                    "权限不存在"
            );
        }
    }
}
